// socket/socket-manager.js

const MAX_CONNECTIONS = 200;

const { handlePlayerJoin, handlePlayerMove } = require('./player-handler');
const { handleAttack } = require('./monster-handler');
const { handleChat } = require('./chat-handler');

// 🔥 全局映射表
const userSocketMap = new Map(); // userId → socket （用于防重复登录）
const jobSocketMap = new Map();  // jobId → socket  （用于游戏内操作）

async function setupSocketHandlers(socket, io) {
  const { query } = socket.handshake;

  // 1. 检查 userId（登录态）
  if (!query.userId) {
    socket.emit('error', { message: '缺少用户ID' });
    socket.disconnect();
    return;
  }

  const userId = query.userId;

  // 2. 防止重复登录：踢出旧连接
  if (userSocketMap.has(userId)) {
    const oldSocket = userSocketMap.get(userId);
    console.log(`[Auth] 用户 ${userId} 已在线，踢出旧连接`);
    oldSocket.emit('kicked', { reason: '账号在别处登录' });
    oldSocket.disconnect();
  }

  // 3. 挂载身份信息
  socket.userId = userId;
  socket.jobId = null; // 初始为 null，join 后赋值

  // 4. 存入 userId 映射
  userSocketMap.set(userId, socket);

  // 5. 检查最大连接数
  if (io.engine.clientsCount > MAX_CONNECTIONS) {
    socket.emit('error', { message: '服务器拥挤' });
    socket.disconnect();
    return;
  }

  console.log(`[Socket] 用户连接: ${userId} (Socket ID: ${socket.id})`);

  // 6. 监听事件
  socket.on('join', (data) => {
    handlePlayerJoin(socket, data, jobSocketMap);
  });

  socket.on('move', (data) => {
    handlePlayerMove(socket, data, io);
  });

  socket.on('attack', (monsterId) => {
    handleAttack(socket, monsterId, io);
  });

  socket.on('chat', (data) => {
    handleChat(socket, data, io);
  });

  // 7. 断开连接清理
  socket.on('disconnect', (reason) => {
    console.log(`[Disconnect] ${userId} 离开，原因: ${reason}`);

    // 清理 jobId 映射
    if (socket.jobId) {
      jobSocketMap.delete(socket.jobId);
    }

    // 清理 userId 映射
    userSocketMap.delete(userId);

    // 从游戏状态中移除玩家
    if (socket.jobId) {
      const playerInfo = require('./game-state').findPlayer(socket.jobId);
      if (playerInfo) {
        const { map } = playerInfo;
        socket.leave(map);
        require('./game-state').removePlayer(map, socket.jobId);
        socket.to(map).emit('playerLeave', socket.jobId);
        socket.to(map).emit('chat', {
          type: 'system',
          text: `${socket.jobId} 离开了游戏`,
          map
        });
      }
    }
  });
}

module.exports = { setupSocketHandlers, userSocketMap, jobSocketMap };